/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.ejb.controlador;

import java.io.Serializable;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.enterprise.context.SessionScoped;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.inject.Named;
import org.ejb.controlador.util.JsfUtil;
import org.ejb.controlador.util.PaginationHelper;
import org.ejb.negocio.JuegosFacade;
import org.ejb.negocio.UsuariosFacade;
import org.ejb.negocio.ValoracionesFacade;
import org.ejb.persistencia.Juegos;
import org.ejb.persistencia.Usuarios;
import org.ejb.persistencia.Valoraciones;



/**
 * Esta clase representa el controlador para que el administrador pueda realizar
 * las tareas pertinentes. En principio debe poder listar y eliminar cualquier 
 * elemento en la bbdd.
 * @author MoisesAntonio
 */
@Named("adminController")
@SessionScoped
public class AdminController implements Serializable{
    
    //Modelos del sistema
    private Juegos cuJuegos;
    private Usuarios cuUsuarios;
    private Valoraciones cuValoracion;
    
    private DataModel itemsValoraciones = null;
    private DataModel itemsUsuarios = null;
    private DataModel itemsJuegos = null;
    
    //Estas clases son necesarias para el control de la app.
    @EJB
    private org.ejb.negocio.JuegosFacade ejbJuegos;
    @EJB
    private org.ejb.negocio.UsuariosFacade ejbUsuarios;
    @EJB
    private org.ejb.negocio.ValoracionesFacade ejbValoraciones;
    
    //Estos objetos permiten paginar la web, por defecto he limitado a 10 el número de items por tabla.
    private PaginationHelper paginationValoraciones;
    private PaginationHelper paginationUsuarios;
    private PaginationHelper paginationJuegos;
    
    //Estos son los marcadores que indica que página mostrar.
    private int selectedItemIndexJuegos;
    private int selectedItemIndexUsuario;
    private int selectedItemIndexValoracion;
    
    //Constructor vacio, tipico en los ManagedBeans.
    public AdminController(){}
    
    /**
     * Metodo para obtener el juego seleccionado.
     * @return Objeto Juegos.
     */
    public Juegos getSelectedJuegos() {
        if (cuJuegos == null) {
            cuJuegos = new Juegos();
            selectedItemIndexJuegos = -1;
        }
        return cuJuegos;
    }
    
    /**
     * Metodo para obtener el Usuario seleccionado
     * @return Objeto Usuario.
     */
    public Usuarios getSelectedUsuarios() {
        if (cuUsuarios == null) {
            cuUsuarios = new Usuarios();
            selectedItemIndexUsuario = -1;
        }
        return cuUsuarios;
    }
    
    /**
     * Método para obtener la Valoración seleccionada.
     * @return Objeto Valoración.
     */
    public Valoraciones getSelectedValoraciones() {
        if (cuValoracion == null) {
            cuValoracion = new Valoraciones();
            selectedItemIndexValoracion = -1;
        }
        return cuValoracion;
    }
    
    /**
     * Devuelve el Enterprise JavaBean que controla en capa de negocio las valoraciones.
     * @return EJB de las Valoraciones.
     */
    private ValoracionesFacade getFacadeValoraciones() {
        return ejbValoraciones;
    }
    
    /**
     * Devuelve el Enterprise JavaBean que controla en capa de negocio los Juegos.
     * @return EJB de Juegos.
     */
    private JuegosFacade getFacadeJuegos() {
        return ejbJuegos;
    }
    
    /**
     * Devuelve el Enterprise JavaBean que controla en capa de negocio los Usuarios.
     * @return EJB de Usuarios.
     */
    private UsuariosFacade getFacadeUsuarios() {
        return ejbUsuarios;
    }
    
    /**
     * Este método devuelve la paginación para rellenar una tabla
     * con los objetos Valoraciones.
     * @return PaginationHelper de uso exclusivo para las Valoraciones.
     */
    public PaginationHelper getPaginationValoraciones() {
        if (paginationValoraciones == null) {
            paginationValoraciones = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacadeValoraciones().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacadeValoraciones().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return paginationValoraciones;
    }
    
    /**
     * Este método devuelve la paginación para rellenar una tabla
     * con los objetos Juegos.
     * @return PaginationHelper exclusivo para Juegos.
     */
    public PaginationHelper getPaginationJuegos() {
        if (paginationJuegos == null) {
            paginationJuegos = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacadeJuegos().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacadeJuegos().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return paginationJuegos;
    }
    
    /**
     * Este método devuelve la paginación para rellenar una tabla
     * con los objetos Usuarios.
     * @return PaginationHelper exclusivo para Usuarios.
     */
    public PaginationHelper getPaginationUsuarios() {
        if (paginationUsuarios == null) {
            paginationUsuarios = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacadeUsuarios().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacadeUsuarios().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return paginationUsuarios;
    }
    
    /**
     * Este método prepara la lista de valoraciones y controla el flujo de la vista.
     * @return 
     */
    public String prepareListValoraciones() {
        recreateModel();
        return "ListComentarios";
    }
    
    /**
     * Este método prepara la siguiente página de valoraciones y controla el flujo de la vista.
     * @return 
     */
    public String nextValoraciones() {
        getPaginationValoraciones().nextPage();
        recreateModel();
        return "ListComentarios";
    }

    /**
     * Este método prepara la siguiente página de valoraciones y controla el flujo de la vista.
     * @return 
     */
    public String previousValoraciones() {
        getPaginationValoraciones().previousPage();
        recreateModel();
        return "ListComentarios";
    }
    
    /**
     * Este método devuelve una lsita con las valoraciones a mostrar.
     * @return 
     */
    public DataModel getItemsValoraciones() {
        if (itemsValoraciones == null) {
            itemsValoraciones = getPaginationValoraciones().createPageDataModel();
        }
        return itemsValoraciones;
    }
    
    /**
     * Este método prepara la lista de usuarios y controla el flujo de la vista.
     * @return 
     */
    public String prepareListUsuarios() {
        recreateModel();
        return "ListUsuarios";
    }
    
    /**
     * Este método prepara la siguiente página de usuarios y controla el flujo de la vista.
     * @return 
     */
    public String nextUsuarios() {
        getPaginationUsuarios().nextPage();
        recreateModel();
        return "ListUsuarios";
    }

    /**
     * Este método prepara la siguiente página de valoraciones y controla el flujo de la vista.
     * @return 
     */
    public String previousUsuarios() {
        getPaginationUsuarios().previousPage();
        recreateModel();
        return "ListUsuarios";
    }
    
    /**
     * Este método devuelve una lsita con las valoraciones a mostrar.
     * @return 
     */
    public DataModel getItemsUsuarios() {
        if (itemsUsuarios == null) {
            itemsUsuarios = getPaginationUsuarios().createPageDataModel();
        }
        return itemsUsuarios;
    }

    /**
     * Este método prepara la lista de Juegos y controla el flujo de la vista.
     * @return 
     */
    public String prepareListJuegos() {
        recreateModel();
        return "ListJuegos";
    }
    
    /**
     * Este método prepara la siguiente página de Juegos y controla el flujo de la vista.
     * @return 
     */
    public String nextJuegos() {
        getPaginationJuegos().nextPage();
        recreateModel();
        return "ListJuegos";
    }

    /**
     * Este método prepara la siguiente página de Juegos y controla el flujo de la vista.
     * @return 
     */
    public String previousJuegos() {
        getPaginationJuegos().previousPage();
        recreateModel();
        return "ListJuegos";
    }
    
    /**
     * Este método devuelve una lsita con las Juegos a mostrar.
     * @return 
     */
    public DataModel getItemsJuegos() {
        if (itemsJuegos == null) {
            itemsJuegos = getPaginationJuegos().createPageDataModel();
        }
        return itemsJuegos;
    }
    
    /**
     * Limpia los indices de las páginas.
     */
    private void recreateModel() {
        itemsValoraciones = null;
        itemsUsuarios = null;
        itemsJuegos = null;
    }
    
    /**
     * Limpia las paginaciones.
     */
    private void recreatePagination() {
        paginationValoraciones = null;
        paginationJuegos = null;
        paginationUsuarios = null;
    }
    
    /**
     * Prepara para ver una valoración en concreto y controla el flujo de la vista.
     * @return A que web debe saltar.
     */
    public String prepareViewValoraciones() {
        cuValoracion = (Valoraciones) getItemsValoraciones().getRowData();
        selectedItemIndexValoracion = paginationValoraciones.getPageFirstItem() + getItemsValoraciones().getRowIndex();
        return "ViewComentario";
    }
    
    /**
     * Prepara para ver un Juego en concreto y controla el flujo de la vista.
     * @return A que web debe saltar.
     */
    public String prepareViewJuegos() {
        cuJuegos = (Juegos) getItemsJuegos().getRowData();
        selectedItemIndexJuegos = paginationJuegos.getPageFirstItem() + getItemsJuegos().getRowIndex();
        return "ViewJuegos";
    }
    
    /**
     * Prepara para ver un Usuario en concreto y controla el flujo de la vista.
     * @return A que web debe saltar.
     */
    public String prepareViewUsuarios() {
        cuUsuarios = (Usuarios) getItemsUsuarios().getRowData();
        selectedItemIndexUsuario = paginationUsuarios.getPageFirstItem() + getItemsUsuarios().getRowIndex();
        return "ViewUsuario";
    }
    
    public String destroyValoracion() {
        cuValoracion = (Valoraciones) getItemsValoraciones().getRowData();
        selectedItemIndexValoracion = paginationValoraciones.getPageFirstItem() + getItemsValoraciones().getRowIndex();
        performDestroyValoracion();
        recreatePagination();
        recreateModel();
        return "ListComentarios";
    }

    public String destroyAndViewValoracion() {
        performDestroyValoracion();
        recreateModel();
        updateCurrentItemValoracion();
        if (selectedItemIndexValoracion >= 0) {
            return "ViewComentario";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "ListComentarios";
        }
    }

    private void performDestroyValoracion() {
        try {
            getFacadeValoraciones().remove(cuValoracion);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("ValoracionesDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }
    
    private void updateCurrentItemValoracion() {
        int count = getFacadeValoraciones().count();
        if (selectedItemIndexValoracion >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndexValoracion = count - 1;
            // go to previous page if last page disappeared:
            if (paginationValoraciones.getPageFirstItem() >= count) {
                paginationValoraciones.previousPage();
            }
        }
        if (selectedItemIndexValoracion >= 0) {
            cuValoracion = getFacadeValoraciones().findRange(new int[]{selectedItemIndexValoracion, selectedItemIndexValoracion + 1}).get(0);
        }
    }
    
    public String destroyJuego() {
        cuJuegos = (Juegos) getItemsJuegos().getRowData();
        selectedItemIndexJuegos = paginationJuegos.getPageFirstItem() + getItemsJuegos().getRowIndex();
        performDestroyJuego();
        recreatePagination();
        recreateModel();
        return "ListJuegos";
    }

    public String destroyAndViewJuego() {
        performDestroyJuego();
        recreateModel();
        updateCurrentItemJuego();
        if (selectedItemIndexJuegos >= 0) {
            return "ViewJuegos";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "ListJuegos";
        }
    }

    private void performDestroyJuego() {
        try {
            getFacadeJuegos().remove(cuJuegos);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("JuegosDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }
    
    private void updateCurrentItemJuego() {
        int count = getFacadeJuegos().count();
        if (selectedItemIndexJuegos >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndexJuegos = count - 1;
            // go to previous page if last page disappeared:
            if (paginationJuegos.getPageFirstItem() >= count) {
                paginationJuegos.previousPage();
            }
        }
        if (selectedItemIndexJuegos >= 0) {
            cuJuegos = getFacadeJuegos().findRange(new int[]{selectedItemIndexJuegos, selectedItemIndexJuegos + 1}).get(0);
        }
    }
    
    public String destroyUsuario() {
        cuUsuarios = (Usuarios) getItemsUsuarios().getRowData();
        selectedItemIndexUsuario = paginationUsuarios.getPageFirstItem() + getItemsUsuarios().getRowIndex();
        performDestroyJuego();
        recreatePagination();
        recreateModel();
        return "ListUsuarios";
    }

    public String destroyAndViewUsuario() {
        performDestroyUsuario();
        recreateModel();
        updateCurrentItemUsuario();
        if (selectedItemIndexUsuario >= 0) {
            return "ViewUsuario";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "ListUsuarios";
        }
    }

    private void performDestroyUsuario() {
        try {
            getFacadeUsuarios().remove(cuUsuarios);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("UsuariosDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }
    
    private void updateCurrentItemUsuario() {
        int count = getFacadeUsuarios().count();
        if (selectedItemIndexUsuario >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndexUsuario = count - 1;
            // go to previous page if last page disappeared:
            if (paginationUsuarios.getPageFirstItem() >= count) {
                paginationUsuarios.previousPage();
            }
        }
        if (selectedItemIndexUsuario >= 0) {
            cuUsuarios = getFacadeUsuarios().findRange(new int[]{selectedItemIndexUsuario, selectedItemIndexUsuario + 1}).get(0);
        }
    }
}
